<!--文件列表-->
<template>
  <div>

    <!--目录-->
    <div class="file-irectory clear" v-if="isDirectory">
      <span @click="fileHome" class="inline font-14" :class="{color: titleColor}">{{title}}</span>
      <div class="inline folder-tree">
        <span
          v-for="item in folderChild"
          class="folderNav">
          <i class="iconfont icon-r-arrow font-14"></i>
          <span
            class="ellipsis cursor-pointer"
            @click="folderHandle(item)"
            :title="item.fileName">{{item.fileName}}</span>
      </span>
      </div>

      <div class="right">
        <slot name="right"></slot>
      </div>
    </div>

    <div class="file-title clear">
      <zz-check v-if="checkAll" checkTip="本页全选" @handleChange="handleAllCall" :check = checkedAll marginLeft="10px"></zz-check>
      <div
        class="file-move"
        @mouseleave="mouseleave"
        v-if="isMove">
        <span @click="schDirectory">移动</span>
        <zz-tree
          v-if="showMoveDirectory"
          :isLazy="true"
          :treeData="classifyTree"
          :options="classifyOptions"
          @node-click="moveDirectory"
          class="move-list">
        </zz-tree>
      </div>
      <span v-if="delAll" @click="delSelectFile">删除</span>
      <div class="right">
        <slot name="titleRight"></slot>
      </div>
    </div>

    <!--列表-->
    <zz-none v-if="fileList.length === 0" content="暂无数据"></zz-none>
    <zz-row
      v-else
      :key="item.fileUuid || item.url"
      class="file-list"
      v-for="item in fileList">
      <zz-col :span="6">
        <!--是否显示选择框-->
        <zz-check v-if="check" class="file-check" :data = item :check = item.checked @handleChange="handleLoneCall"></zz-check>

        <!--是否只显示文件类型-->
        <div class="inline" v-if="allFolder && item.docType ===2">
          <i class="iconfont icon-folder"></i>
        </div>

        <div class="file-ico" v-else-if="allFolder && item.docType ===1">
          <i class="iconfont icon-file"></i>
        </div>

        <zz-preview :item="item" v-else></zz-preview>

        <div class="inline ml5">
          <!--跳到二级目录-->
          <p class="folder" v-if="item.docType ===2" :title="item.fileName" @click="folder(item)"><b>{{item.fileName}}</b></p>
          <p v-else :title="item.fileName"><b>{{item.fileName}}</b></p>
          <p class="small">{{item.time | date('YYYY-MM-DD HH:mm:ss', item.time)}}</p>
        </div>
      </zz-col>

      <zz-col :span="3" v-if="cName">
        <p></p>
        <p class="small" v-if="item.mname">创建人：{{item.mname}}</p>
      </zz-col>

      <zz-col :span="cName ? 3 : 6">
        <p></p>
        <p class="small">
          <span v-if="item.fileSize">大小：{{item.fileSize | formatSize}}</span>
          <span
            class="file-type"
            v-if="item.files"
            @click="download(file)"
            v-for="file in item.files">{{file.type}}</span>
        </p>
      </zz-col>

      <!--操作栏-->
      <zz-col :span="12" style="text-align: right;">
        <p></p>
        <small class="operation" v-if="(item.isView === 1 || isPreview) && item.isPreview && item.docType === 1" @click="FilePreview(item)">预览</small>
        <small class="operation" v-if="(item.isDown === 1 || isDown) && item.docType === 1" @click="download(item)">下载</small>
        <small class="operation" v-if="(item.isManager || isDel)" @click="deleteFile(item)">删除</small>
        <small class="operation" v-if="(item.isManager || isReset)" @click="resetFile(item)">重命名</small>
        <small class="operation" v-if="item.edit && item.docType ===1" @click="editFile(item)">编辑</small>
        <small class="operation" v-if="(item.auth || item.isManager) && item.docType ===2 && auth" @click="authFile(item)">权限</small>
        <zz-select
          v-if = "item.isManager || isMore"
          :options = "{width: '40px'}"
          type = 'other'
          :data = "item"
          :option = "selectOption"
          :triangle = false
          fontSize="0.75rem"
          name = '更多'
          @optionClick="optionHandle"></zz-select>
      </zz-col>
    </zz-row>
  </div>
</template>

<script>
  export default {
    name: 'zz-fileList',
    data () {
      return {
        fileList: [],
        directoryList: [],
        showMoveDirectory: false,
        dataMap: new Set(),
        folderMap: new Map(),
        folderChild: [],
        checkedAll: false,
        classifyTree: [{
          label: '根目录',
          checked: false,
          isRoot: true,
          open: false,
          children: []
        }],
        classifyOptions: {
          lazy: true,
          load: this.loadingChild
        },
        documentIds: [],
        selectOption: {
          1: '上移',
          2: '下移'
        },
        list: [{
          src: '',
          w: 1200,
          h: 400
        }]
      }
    },
    props: {
      items: {
        type: Array,
        default: function () {
          return []
        }
      },
      title: {
        type: String,
        default: '文件列表'
      },
      titleColor: {
        type: Boolean,
        default: false
      },
      // 是否开启复选框
      check: {
        type: Boolean,
        default: false
      },
      // 是否开启权限按钮
      auth: {
        type: Boolean,
        default: false
      },
      // 是否显示创建人
      cName: {
        type: Boolean,
        default: true
      },
      // 是否显示移动按钮
      isMove: {
        type: Boolean,
        default: false
      },
      // 是否显示选择全部
      checkAll: {
        type: Boolean,
        default: false
      },
      // 是否开启顶部栏删除按钮
      delAll: {
        type: Boolean,
        default: false
      },
      // 是否显示删除按钮
      isDel: {
        type: Boolean,
        default: false
      },
      // 是否开启预览
      isPreview: {
        type: Boolean,
        default: false
      },
      // 是否开启下载
      isDown: {
        type: Boolean,
        default: false
      },
      // 是否重命名
      isReset: {
        type: Boolean,
        default: true
      },
      // 是否显示目录 路径
      isDirectory: {
        type: Boolean,
        default: false
      },
      // 是否显示移动按钮
      isMore: {
        type: Boolean,
        default: true
      },
      resetFolder: {
        type: Number,
        default: 0
      },
      allFolder: {
        type: Boolean,
        default: false
      },
      previewWidth: {
        type: String
      },
      previewHeight: {
        type: String
      },
      moveUrl: '',
      moveData: '',
      moveQuery: '',
      pjId: null
    },
    watch: {
      items (newValue) {
        this.fileList = newValue.map((file) => {
          if (file.type === 4) {
            let start = this.$previewFile(file)
            this.$set(file, 'isPreview', start)
          } else {
            this.$set(file, 'isPreview', true)
          }
          return file
        })
        this.checkedAll = false
        this.dataMap.clear()
      },
      resetFolder () {
        this.folderMap.clear()
      }
    },
    mounted () {
      this.fileList = this.items
    },
    methods: {
      // 编辑文件
      editFile (item) {
        Object.assign(item, {handleType: 1})
        this.$emit('handle', item)
      },

      // 删除单个文件
      deleteFile (item) {
        Object.assign(item, {handleType: 2})
        this.$emit('handle', item)
      },

      // 重命名
      resetFile (item) {
        Object.assign(item, {handleType: 3})
        this.$emit('handle', item)
      },

      // 权限设置
      authFile (item) {
        Object.assign(item, {handleType: 4})
        this.$emit('handle', item)
      },

      // 移动多个文件
      moveFile (item) {
        this.$emit('handle', {
          data: [...this.dataMap.values()],
          handleType: 5
        })
      },

      // 删除多个文件
      delSelectFile () {
        this.$emit('handle', {
          data: [...this.dataMap.values()],
          handleType: 6
        })
        this.dataMap.clear()
      },

      // 跳到二级目录
      folder (item) {
        if (this.folderMap.has(item.parentId)) {
          this.folderMap.set(item.docId, item)
        } else {
          this.folderMap.clear()
          this.folderMap.set(item.docId, item)
        }
        this.folderChild = [...this.folderMap.values()]
        Object.assign(item, {handleType: 7})
        this.$emit('handle', item)
      },

      // 跳到其中某个目录
      folderHandle (item) {
        if (!this.folderMap.has(item.docId)) {
          this.folderMap.clear()
          this.folderChild = []
        }
        this.removeFolder(item.docId)
        Object.assign(item, {handleType: 7, isFolder: true})
        this.$emit('handle', item)
      },

      // 移除后面目录
      removeFolder (docId) {
        let length = 0
        this.folderChild.forEach((el, i) => {
          if (el.docId === docId) {
            length = i
          }
        })
        this.folderChild.splice(0, length + 1)
        this.folderChild.forEach(x => {
          this.folderMap.delete(x.docId)
        })
        this.folderChild = [...this.folderMap.values()]
      },

      // 跳到首页列表
      fileHome () {
        this.folderMap.clear()
        this.folderChild = []
        this.$emit('handle', {handleType: 7, home: true})
      },

      // 文件上下移
      optionHandle (data) {
        if (data.key === '1') {
          Object.assign(data.value, {handleType: 8})
        } else {
          Object.assign(data.value, {handleType: 9})
        }
        this.$emit('handle', data.value)
      },

      // 下载文件
      download (file) {
        this.$Download(file.fileUuid, file.fileName)
      },

      // 选单个文件
      handleLoneCall (obj) {
        const {state, value} = obj
        if (state) {
          this.dataMap.add(value)
        } else {
          this.dataMap.delete(value)
        }
      },

      // 全选文件
      handleAllCall (state) {
        this.fileList.forEach(el => {
          el.checked = state
          this.dataMap.add(el)
        })
        if (!state) {
          this.dataMap.clear()
        }
      },

      // 文件预览
      FilePreview (file) {
        switch (file.type) {
          case 1:
            this.previewImage(file)
            break
          case 2:
            // this.$Open(`/front/preview.htm?query.fileUrl=${file.url}`)
            break
          case 3:
            this.$video.open(file.url)
            break
          case 4:
            this.$pdf.open(file.fileUuid || file.url)
            break
        }
      },

      // 预览图片
      previewImage (file) {
        this.$store.dispatch({
          type: 'downFile',
          fileUuid: file.fileUuid,
          th: 1
        }).then(res => {
          // Success handle
          this.src = res
          const image = new Image()
          image.src = res
          image.onload = () => {
            this.list.forEach(x => {
              x.src = res
              x.w = image.width
              x.h = image.height
            })
            this.$preview.open(0, this.list)
          }
        }, err => {
          // Error handle
          this.$message.error(err)
        })
      },

      // 移动到其它目录
      moveDirectory (node) {
        node = {...node, ...{file: [...this.dataMap.values()]}, ...{handleType: 10}}
        this.$emit('handle', node)
      },
      schDirectory () {
        this.showMoveDirectory = true
        const data = {}
        data[this.moveQuery] = this.moveData
        this.$axios({
          method: 'post',
          url: this.moveUrl,
          data: this.$qs.stringify(data, {indices: false})
        }).then(res => {
          if (res.data.errorMsg) {
            this.$message.error(res.data.errorMsg)
          } else {
            if (res.data.list) {
              this.directoryList = res.data.list
            } else {
              this.directoryList = []
            }
          }
        })
      },
      // 获取子文件夹
      async loadingChild (node) {
        let data = await new Promise((resolve) => {
          const arr = []
          this.directoryList.forEach(x => {
            if (node.isRoot) {
              if (!x.parent_id) {
                this.$set(x, 'checked', false)
                Object.assign(x, {label: x.classify_name})
                Object.assign(x, {classify_id: x.classify_id})
                arr.push(x)
              }
            } else {
              if (node.classify_id === x.parent_id) {
                this.$set(x, 'checked', false)
                Object.assign(x, {label: x.classify_name})
                Object.assign(x, {classify_id: x.classify_id})
                arr.push(x)
              }
            }
          })
          resolve(arr)
        })
        let tem = this.getParentNode(node, this.classifyTree)
        this.$set(tem, 'children', data)
        Promise.resolve(data)
      },
      getParentNode (node, treeData) {
        let tem
        let postions = node.key.split('-')
        for (let [index, item] of postions.entries()) {
          switch (index) {
            case 0:
              break
            case 1:
              tem = treeData[item]
              break
            default:
              tem = tem.children[item]
          }
        }
        return tem
      },
      mouseleave () {
        this.showMoveDirectory = false
        this.classifyTree[0].open = false
        delete this.classifyTree[0].loaded
      }
    }
  }
</script>
<style lang="scss">
  .font-14 {
    font-size: 14px;
  }
  .cursor-pointer {
    cursor: pointer;
  }
  .file-title{
    line-height: 20px;
    margin-bottom: 10px;
    text-align: left;
    .file-move{
      display: inline-block;
      vertical-align: top;
      margin-left: 25px;
      cursor: pointer;
      position: relative;
      >span{
        &:hover{
          color: $color;
        }
      }
      .move-list{
        position: absolute;
        top: 20px;
        left: 0;
        background: #fff;
        border-radius: 3px;
        width: 300px;
        height: 200px;
        overflow: auto;
        z-index: 2;
        padding: 10px;
        box-sizing: border-box;
        @include shadow
      }
    }
    >span{
      vertical-align: top;
      margin-left: 25px;
      cursor: pointer;
      &:hover{
        color: $color;
      }
    }
  }
  .file-irectory{
    margin:0 0 20px 0;
    padding-bottom: 10px;
    line-height: 30px;
    border-bottom: 1px $color-line solid;
    .folder-tree{
      vertical-align: top;
      >span{
        &:last-child{
          color: $color;
        }
      }
    }
    > span{
      cursor: pointer;
      &:hover{
        color: $color;
      }
    }
  }
  .folderNav{
    height: 100%;
    display: inline-block;
    vertical-align: top;
    .icon-right{
      font-size: 0.75rem;
    }
  }

  .file-list{
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 1px $color-line solid;
    .checkeds{
      margin-right: 10px;
    }
    .folder{
      cursor: pointer;
      &:hover{
        color: $color;
      }
    }
    .file-ico{
      display: inline-block;
      width: 40px;
      height: 40px;
      line-height: 30px;
      color: #fff;
      text-align: center;
      background: $color;
    }
    &:last-child{
      margin-bottom: 0;
    }
    .file-check{
      vertical-align: top;
      margin-top: 12px;
    }
    .icon-folder{
      color: #fcba4a;
      background: #f7a61d;
      font-size: 47px;
      position: absolute;
      top: -4px;
      left: -4px;
    }
    .file-route{
      cursor: pointer;
      &:hover{
        color: $color;
      }
    }
    p{
      height: 16px;
      width: 160px;
      @include ellipsis
    }
    .small{
      color: $color-grid;
      font-size: $font-size-smallest;
      display: inline-block;
      margin-top: 5px;
      >span{
        margin-right: 20px;
      }
      .file-type{
        cursor: pointer;
        color: $color;
        &:hover{
          color: $color-hover;
        }
      }
    }
    .operation{
      cursor: pointer;
      display: inline-block;
      margin-right: 15px;
      &:hover{
        color: $color;
      }
    }
    .select-com{
      margin-top: -7px;
      padding-left: 0;
      .select-trigger{
        span{
          font-size: 12px;
          color: $color-grid;
        }
      }
    }
  }
</style>
